home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / games / IndiZone / gold / gold.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  14.1 KB  |  571 lines

  1. /*
  2.  * The original copyright owners of the accompanying source code files have
  3.  * agreed to place such code into the public domain.  Accordingly, anyone
  4.  * who receives or obtains a copy of such source code is freely entitled to
  5.  * reproduce, use and otherwise exploit such code (including the right to
  6.  * make derivative works), at his/her own risk and expense, without any
  7.  * obligation or liability to the original copyright owners.
  8.  *
  9.  * We would appreciate (but do not require) that the following message be
  10.  * included in any derivative works:
  11.  *
  12.  * "Portions of this program were developed by Peter Broadwell, Rob Myers
  13.  * and Robin Schaufler while working in Silicon Valley."
  14.  *
  15.  * The accompanying source code files and related documentation materials
  16.  * are distributed on an "AS IS" basis, without any warranties or
  17.  * guarantees of any kind.  All implied warranties, including the implied
  18.  * warranties of merchantability and of fitness for any particular purpose,
  19.  * are expressly disclaimed.
  20.  */
  21. #include <stdlib.h>
  22. #include <stdio.h>
  23. #include <math.h>
  24. #include <gl.h>
  25. #include <device.h>
  26.  
  27. #include "geom.h"
  28. #include "selectors.h"
  29. #include "class.h"
  30. #include "classIds.h"
  31. #include "mbox.h"
  32. #include "individual.h"
  33. #include "panel.h"
  34. #include "behavior.h"
  35. #include "doers.h"
  36. #include "colors.h"
  37. #include "voxel.h"
  38.  
  39. #include "camera.h"
  40. #include "sea.h"
  41. #include "toad.h"
  42. #include "pebbles.h"
  43. #include "egg.h"
  44.  
  45. #include "sys/types.h"
  46. #include "timeb.h"
  47.  
  48. extern struct timeb tb_start, tb_end;        /* timer blocks        */
  49.  
  50. #define PI 3.14159265358979323844
  51. #define DEG(x) ((float)x*(float)180/PI)
  52. #define RAD(x) ((float)x*PI/(float)180)
  53.  
  54. extern unsigned short scaleyTex1[];
  55. extern unsigned short spottyTex2[];
  56.  
  57. extern individual usTemplate;
  58. extern individual indivTemplate;
  59. extern individual minnowTemplate;
  60. extern individual guppyTemplate;
  61. extern individual bubbleMachineTemplate;
  62. extern individual eggTemplate;
  63. extern wiggler  wigglerTemplate;
  64. extern behavior circlerTemplate;
  65. extern behavior swerverTemplate;
  66. extern behavior chameleonTemplate;
  67. extern behavior colorizerTemplate;
  68. extern behavior advancerTemplate;
  69. extern behavior expanderTemplate;
  70. extern behavior surfDieTemplate;
  71. extern behavior metamorphTemplate;
  72. extern behavior maleTemplate;
  73. extern behavior femaleTemplate;
  74. extern behavior feederTemplate;
  75. extern behavior wideyeTemplate;
  76. extern behavior trailGhostTemplate;
  77. extern behavior faderTemplate;
  78. extern camera    cameraTemplate;
  79. extern sea    seaTemplate;
  80. extern toad    toadTemplate;
  81. extern pebbles    pebbleTemplate;
  82. extern mailbox    fullVoxels;
  83. extern masterPanel mPanelTemplate;
  84.  
  85. extern char frozen;
  86. extern char dobackground;
  87. extern char bullet;
  88. extern char timeit;
  89. extern char quit;
  90. extern voxel *bigBang();
  91. extern inst* clone();
  92. int doingRGB = 0;
  93.  
  94. individual *us;
  95. camera    *theCamera;
  96. masterPanel *thePanel;
  97. voxel *universe;
  98. point univol = {10000, 10000, 10000};
  99. point voxvol = {1000,  1000,  1000};
  100. point bowlRadius = {4000,  4000,  4000};
  101. long masterClock = 0;
  102. long saveClock = 0;
  103. long newClock = 0;
  104. long fishPop = 0;
  105. long numgups;
  106. int unsophistication = 98;
  107. point2d  curWindow;
  108. point2df scalePanel;
  109.  
  110. int landscape = TRUE;    /* put in the seaweed and pebles */
  111. int egg_flag = TRUE;    /* should sexual reproduction take place */
  112. int bub_flag = TRUE;    /* should there be any bubles */
  113. int feed_flag = TRUE;    /* should they try and eat each other */
  114. int toad_flag = FALSE;    /* is there a toad on the floor - doesn't work yet */
  115. int ghost_flag = FALSE;    /* attempt at making trails - doesn't work yet */
  116. int video_flag = FALSE;    /* should be video sized with large cursor */
  117. int controls = TRUE;    /* show controls by default */
  118. int allbuttons = TRUE;    /* make all mouse buttons behave the same */
  119. int maldbug = FALSE;    /* enable malloc debuging - only with FUNNY_MALLOC */
  120. int dumper = FALSE;    /* be noisy and print subscriber lists */
  121. int (*subscrFcn)();
  122. extern subscribe(), halfsubscr();
  123.  
  124. Cursor arrow = {
  125. 0x8080,
  126. 0xc1c0,
  127. 0xe3e0,
  128. 0xf7f0,
  129. 0xfff8,
  130. 0xfffc,
  131. 0xfffe,
  132. 0xffff,
  133. 0xfffe,
  134. 0xfffc,
  135. 0xfff8,
  136. 0xfff0,
  137. 0xfff8,
  138. 0xfffc,
  139. 0xfffe,
  140. 0xffff,
  141. };
  142.  
  143. main(argc,argv,envp)
  144.     int argc;
  145.     char *argv[], **envp;
  146. {
  147.     int c;
  148.     int errflg = 0;
  149.  
  150.     while ((c = getopt(argc, argv, "bceflmv")) != -1) {
  151.     switch (c) {
  152. /*
  153.         case 'a':
  154.         allbuttons = !allbuttons;
  155.         break;
  156. */
  157.         case 'b':
  158.         bub_flag = !bub_flag;
  159.         break;
  160.         case 'c':
  161.         controls = !controls;
  162.         break;
  163. /*
  164.         case 'd':
  165.         dumper = !dumper;
  166.         break;
  167. */
  168.         case 'e':
  169.         egg_flag = !egg_flag;
  170.         break;
  171.         case 'f':
  172.         feed_flag = !feed_flag;
  173.         break;
  174. /*
  175.         case 'g':
  176.         ghost_flag = !ghost_flag;
  177.         break;
  178. */
  179.         case 'l':
  180.         landscape = !landscape;
  181.         break;
  182.         case 'm':
  183.         maldbug = !maldbug;
  184.         break;
  185.         case 'v':
  186.         video_flag = !video_flag;
  187.         break;
  188. /*
  189.         case 't':
  190.         toad_flag = !toad_flag;
  191.         break;
  192. */
  193.         default:
  194.         usage();
  195.         break;
  196.     }
  197.     }
  198.     if (errflg) {
  199.         usage();
  200.     }
  201.  
  202.     if (egg_flag) {
  203.     subscrFcn = halfsubscr;
  204.     } else {
  205.     subscrFcn = subscribe;
  206.     }
  207.  
  208.     setup(video_flag);
  209.     tic();
  210.     system("/usr/sbin/makemap");
  211.     gexit();
  212. }
  213.  
  214.  
  215. usage()
  216. {
  217.     fprintf(stderr,"usage:  gold [-bceflmv]\n");
  218.     fprintf(stderr,"      -b   don't display the bubbles visible by default\n");
  219.     fprintf(stderr,"      -c   don't show the controls visible by default\n");
  220.     fprintf(stderr,"      -e   prevent sexual reproduction from taking place\n");
  221.     fprintf(stderr,"      -f   keep fish from eating each other (mightn't work--old debug cruft)\n");
  222.     fprintf(stderr,"      -l   don't display the landscape visible by default\n");
  223.     fprintf(stderr,"      -m   enable's malloc debugging\n");
  224.     fprintf(stderr,"      -v   open as 640x480 NTSC video-sized window w/large cursor\n");
  225. }
  226.  
  227.     /*
  228.      *  setup the fishbowl parameters for E-Z viewing pleasure
  229.      */
  230. setup(vidp)
  231. {
  232.     foreground();
  233.     
  234.     if(!vidp)
  235.     prefposition(0,getgdesc(GD_XPMAX),0,getgdesc(GD_YPMAX));
  236.     else
  237.     prefposition(0,640, 0,480);
  238.     winopen("gold");
  239.     getsize(&curWindow.x, &curWindow.y);
  240.     if(vidp) {
  241.     defcursor(1,arrow);
  242.     curorigin(1,0,16);
  243.     setcursor(1,0,0);
  244.     }
  245.     winattach();
  246.  
  247.     /* set scaling of control Panel viewport to WC */
  248.     scalePanel.x = 256.0 / (float)(curWindow.x - curWindow.y);
  249.     scalePanel.y = 767.0 / (float)curWindow.y;
  250.  
  251.     setdepth(-20000,20000);
  252.     qdevice(BKEY);
  253.     qdevice(FKEY);
  254.     qdevice(QKEY);
  255.     qdevice(SKEY);
  256.     qdevice(ZKEY);
  257.     qdevice(ESCKEY);
  258.     qdevice(VIRGULEKEY);
  259.     qdevice(LEFTMOUSE);
  260.     qdevice(MIDDLEMOUSE);
  261.     qdevice(RIGHTMOUSE);
  262.  
  263.     backface(TRUE);
  264.     picksize(1,1);
  265.     defpattern(SCALEY_TEX1, 16, scaleyTex1);
  266.     defpattern(SPOTTY_TEX2, 16, spottyTex2);
  267.     setColorMap();
  268.     fishColor(WATER_COLOR);
  269.     clear();
  270.     doublebuffer();
  271.     drawmode(NORMALDRAW);
  272.     if(getgdesc(GD_BITS_NORM_DBL_CMODE) < 12) {
  273.     doingRGB = 1;
  274.     RGBmode();
  275.     }
  276.     gconfig();
  277.     initsort();
  278.  
  279.     /* fish story begins here */
  280.     universe = bigBang(&univol, &voxvol);
  281.  
  282.     Expand(&usTemplate);
  283.     Expand(&surfDieTemplate);
  284.     Expand(&expanderTemplate);
  285.     Expand(&advancerTemplate);
  286.     Expand(&wigglerTemplate);
  287.     Expand(&circlerTemplate);
  288.     Expand(&swerverTemplate);
  289.     Expand(&chameleonTemplate);
  290.     Expand(&colorizerTemplate);
  291.     Expand(&metamorphTemplate);
  292.     Expand(&maleTemplate);
  293.     Expand(&femaleTemplate);
  294.     Expand(&feederTemplate);
  295.     Expand(&wideyeTemplate);
  296.     Expand(&fullVoxels);
  297.     Expand(&mPanelTemplate);
  298.     Expand(&trailGhostTemplate);
  299.     Expand(&faderTemplate);
  300. }
  301.  
  302.     /*
  303.      *  tic off the rendering clock
  304.      */
  305. tic()
  306. {
  307.     register individual *newone;
  308.     register subscr *sentry, *nentry;
  309.     register int i, j;
  310.     point2df newhead;
  311.     circlerVars *initCircler;
  312.     swerverVars *initSwerver;
  313.     metamorphVars *initMeta;
  314.     extern mailbox fullVoxels;
  315.     individual *newovum;
  316.     static int lastun = 100;
  317.     static int backlev[] = { 40, 60, 63, 70, 77, 80};
  318.  
  319.         /* us keeps track of everybody who wants to get "tic'd" off */
  320.     us = &usTemplate;
  321.  
  322. #define ICOUNT 1
  323. #ifdef LONELY
  324. #define MCOUNT 1    /* number of minnows */
  325. #define GCOUNT 1    /* number of guppies + minnows */
  326. #define SCOUNT 0    /* number of seaweeds */
  327. #else /* LONELY */
  328. #define MCOUNT 3    /* number of minnows */
  329. #define GCOUNT 5    /* number of guppies + minnows */
  330. #define SCOUNT 3    /* number of seaweeds */
  331. #endif /* LONELY */
  332.  
  333.         /* build many fish */
  334.     for (i=ICOUNT; i<=GCOUNT; i++) {
  335.     if (i<=MCOUNT)
  336.         newone = (individual *)clone(&minnowTemplate);
  337.     else
  338.         newone = (individual *)clone(&guppyTemplate);
  339.  
  340.         /* clone the individual's model description; add it to us */
  341.     Msg(newone, INIT, NOARG, NULL);
  342.     subscrFcn(us, newone);
  343.  
  344.     newone->scale = (long)(0.43 * i) + 2;
  345.  
  346.     if (egg_flag && i <= MCOUNT) {    /* minnows can reproduce now */
  347.         if (i==ICOUNT) {
  348.         subscrFcn(&maleTemplate, newone);
  349.         } else {
  350.         subscrFcn(&femaleTemplate, newone);
  351.         }
  352.     }
  353.     if (egg_flag && i > MCOUNT) {    /* guppies can reproduce now */
  354.         if (i==MCOUNT+1) {
  355.         subscrFcn(&maleTemplate, newone);
  356.         } else {
  357.         subscrFcn(&femaleTemplate, newone);
  358.         }
  359.     }
  360.  
  361.     if (feed_flag && i <= MCOUNT) {    /* minnows can eat now */
  362.         subscrFcn(&feederTemplate, newone);
  363.     }
  364.  
  365.     if (ghost_flag && i == 1) {
  366.         subscrFcn(&trailGhostTemplate, newone);
  367.     }
  368.  
  369.         /* behavior messages will happen from head to tail of subscr list */
  370.     subscrFcn(&wigglerTemplate, newone);
  371.     ((wigglerVars *)findvars(newone,WIGGLER))->wiggleClock = 7 * i;
  372.  
  373.     subscrFcn(&swerverTemplate, newone);
  374.     /****
  375.     initSwerver = (swerverVars *)findvars(newone,SWERVER);
  376.     initSwerver->maxvelocity.x = 50 + (10 * i);
  377.     initSwerver->maxvelocity.y = 70 + (8 * i);
  378.     initSwerver->maxvelocity.z = 20 + (2 * i);
  379.     ******/
  380.     newone->position.x = 100 * i * (odd(i) ? 1 : -1);
  381.     newone->position.y = 200 * i * (odd(i>>1) ? 1 : -1);
  382.     newone->position.z = 100 * i * (odd(i>>1) ? -1 : 1);
  383. #ifdef LONELY
  384.     newone->speed = 20.0 * i;
  385.     newone->heading.x = 1.0;
  386.     newone->heading.y = 0.0;
  387.     newone->heading.z = 0.0;
  388.     normalize(&newone->heading.x);
  389.     bullet = TRUE;        /* draw axes to see space more clearly */
  390. #else  /* LONELY */
  391.     newone->speed += (14 * i);
  392.     newone->heading.x *= (odd(i) ? 1 : -1);
  393.     newone->heading.y *= (odd(i>>1) ? 1 : -1);
  394.     newone->heading.z *= (odd(i) ? 1 : -1);
  395.     normalize(&newone->heading.x);
  396. #endif /* LONELY */
  397.  
  398.     if (! egg_flag)
  399.         newVoxPosition(universe, &newone->position, newone);
  400.  
  401.     if (egg_flag) {
  402.         newovum = (individual *)clone(&eggTemplate);
  403.         subscribe(&metamorphTemplate, newovum);
  404.         initMeta = (metamorphVars *)newovum->them.subscribedTo;
  405.         initMeta->embryo = newone;
  406.         initMeta->alarm = 20 * i;
  407.         newovum->position = newone->position;
  408.         newVoxPosition(universe, &newovum->position, newovum);
  409.         subscribe(us, newovum);
  410.         Msg(newovum, INIT, 0, NULL);
  411.     }
  412.     }    /* for i */
  413.  
  414.         /* last guppy is a colorizer */
  415.     if (newone) {
  416.     subscrFcn(&colorizerTemplate, newone);
  417.     }
  418.  
  419.     if (bub_flag) {
  420.         /* build bubbles */
  421.     newone = (individual *)clone(&bubbleMachineTemplate);
  422.     Msg(newone, INIT, NOARG, NULL);
  423.     subscribe(us, newone);
  424.     }
  425.  
  426.         /* initialize toadStone */
  427.     if(toad_flag) {
  428.     newone = (individual *)clone(&toadTemplate);
  429.     Msg(newone, INIT, NOARG, NULL);
  430.     subscribe(us, newone);
  431.     }
  432.  
  433.     if (landscape) {
  434.         /* build seaweeds */
  435.     for (i=1, j=1; i<=SCOUNT; i++) {
  436.         newone = (individual *)clone(&seaTemplate);
  437.         j = -j;
  438.         ((sea *)newone)->length += j*(-10);
  439.         Msg(newone, INIT, sizeof(point), &univol);
  440.         newone->position.y *= j;
  441.         if (i==1)
  442.         newone->rotation.z += 450;
  443.         if (i==3) {
  444.         newone->position.x = -1500;
  445.         newone->position.y = -3500;
  446.         }
  447.         subscribe(us, newone);
  448.     }
  449.         /* build a floor of pebbles */
  450.     newone = (individual *)clone(&pebbleTemplate);
  451.     Msg(newone, INIT, sizeof(point), &univol);
  452.     subscribe(us, newone);
  453.     }
  454.  
  455.         /* build a camera and control panel */
  456.     theCamera = (camera *)clone(&cameraTemplate);
  457.     Msg(theCamera, INIT, NOARG, NULL);
  458.     thePanel  = &mPanelTemplate;
  459.  
  460.     saveClock = ftime (&tb_start);/* so we don't get wigged out first timings */
  461.  
  462.     while(1) {
  463.     masterClock++;
  464.         /* setup for this rendering cycle */
  465.     Msg(theCamera, POLL, NOARG, NULL);
  466.     Msg(theCamera, TAKE, NOARG, NULL);
  467.  
  468.     viewport(0,curWindow.y, 0,curWindow.y);
  469.     backface(TRUE);
  470.  
  471.     if(doingRGB)        /* in rgb mode we can't cheat */
  472.         dobackground = 3;
  473.     if (dobackground) {
  474.         fishWritemask(BACKGROUND);
  475.     }
  476.     else {
  477.         fishWritemask(FOREGROUND);
  478.     }
  479.  
  480.     fishColor(WATER_COLOR);
  481.     clear();
  482.  
  483.     if (unsophistication >= 90)
  484.         drawBowl();
  485.  
  486.     if (lastun != unsophistication) {
  487.       for (i=0; i < (sizeof(backlev)/sizeof(int)); i++) {
  488.         if (((lastun < backlev[i]) && (unsophistication >= backlev[i])) ||
  489.         ((lastun > backlev[i]) && (unsophistication <= backlev[i]))) {
  490.             dobackground = 3;
  491.         }
  492.       }
  493.       lastun = unsophistication;
  494.     }
  495.         
  496.     if (quit)
  497.         return;
  498.  
  499.         /* advance the fish story */
  500.     pushmatrix();
  501.  
  502.     if (bullet)
  503.         drawOrig(); /* */
  504.  
  505.         /* update and compile each individual */
  506.     numgups = 0;
  507.     for (sentry = nentry = us->them.subscribers; nentry; sentry = nentry) {
  508.         nentry = sentry->next;
  509.         if(isSuper(sentry->member,GUPPY) ||
  510.               isSuper(sentry->member,EGG)) numgups++;
  511.         pushmatrix();
  512.         Msg(sentry->member, DOIT, INSTARG, us);
  513.         popmatrix();
  514.     }
  515. #ifdef VOX_DEBUG
  516.         /* debug */
  517.     for (sentry=fullVoxels.subscribers; sentry; sentry = sentry->next) {
  518.         drawVoxel(sentry->member);
  519.     }
  520. #endif /* VOX_DEBUG */
  521.     sortobjs(us);
  522.         /* render each guppy from its compiled history */
  523.     callobj((Object)us);
  524.         /* done with this rendering cycle */
  525.     popmatrix();
  526.  
  527.         /* draw other viewport for control panel */
  528.     pushviewport();
  529.     viewport(curWindow.y,curWindow.x, 0,curWindow.y);
  530.     fishWritemask(FOREGROUND);
  531.     fishColor(WATER_COLOR);
  532.     clear();
  533.  
  534.     if (controls) {
  535.         pushmatrix();
  536.         ortho2(0.0,256.0, 767.0,0.0);
  537.         backface(FALSE);
  538.         drawControls(thePanel);
  539.         callobj((Object)thePanel);
  540.         popmatrix();
  541.     }
  542.     popviewport();
  543.  
  544.     swapbuffers();
  545.  
  546.     newClock = ftime (&tb_end);
  547.     if (dobackground>0) dobackground--;
  548. /* HACK: if we get too slow, start over */
  549.     if (timeit) {
  550.         display_time ("main loop", masterClock, 1);
  551.     }
  552.     if ((newClock - saveClock > 120) || (fishPop <= 0) || numgups <= 0) {
  553. #ifdef TIMEOUT
  554. #define TIMEOUT
  555.         return;
  556. #endif /* TIMEOUT */
  557.     }
  558.     saveClock = ftime (&tb_start);
  559. /* END HACK: if we get too slow, start over */
  560. #ifdef FUNNY_MALLOC
  561. while(!getbutton(PADENTER));
  562.     if(maldbug){ long a,f,ac,fc;
  563.         malloc_stats(&a,&f,&ac,&fc);                /***/
  564.         printf("allocated = %d\tfreed = %d\ta_cells =%d\tf_cells =%d\n",a,f,ac,fc);    /***/
  565.     }
  566. #endif /* FUNNY_MALLOC */
  567. #define FUNNY_MALLOC
  568.     }
  569. }
  570.  
  571.